#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>


int main(int argc, char const *argv[])
{
    // 1、创建UDP通信对象
    int  udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (udp_socket < 0)
    {
        perror("创建UDP对象失败!\n");
        return -1;
    }

    // 使套接字sockfd关联的地址在套接字关闭后立即释放
    int on = 1;
    setsockopt(udp_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));  //开启端口复用功能 

    // 2、绑定UDP接收端地址信息 --- 你想接收信息，就一定要设置
    // struct sockaddr *addr;                           // 旧地址结构体，已经废弃掉了
    struct sockaddr_in addr;                            // 创建一个服务器地址结构体
    addr.sin_family      = AF_INET;                     // 设置地址族为IPv4
    addr.sin_port        = htons(8080);                 // 设置端口号为8080
    addr.sin_addr.s_addr = INADDR_ANY;                  // 设置IP地址为本机器的所有地址

    int ret_b = bind(udp_socket, (struct sockaddr *)&addr, sizeof(addr));
    if (ret_b < 0)
    {
        perror("绑定失败!\n");
        return -2;
    }

    // 3、等待发送端的发送数据
    printf("等待发送端的发送数据!\n");

    // 4、保存发送端的地址信息 
    struct sockaddr_in send_addr; 
    int len = sizeof(send_addr);

    // 接收信息
    char buf[1024] = {0};
    ssize_t size = recvfrom(udp_socket, buf, sizeof(buf), 0, (struct sockaddr *)&send_addr, &len);

    // 把网络地址转换为本地地址
    char *ip = inet_ntoa(send_addr.sin_addr);
    int port = ntohs(send_addr.sin_port);
    printf("ip:%s  port:%d  大小:%ld  内容:%s\n", ip, port, size, buf);

    return 0;
}
